home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvi2qms / findfile.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  5KB  |  180 lines

  1. /* findfile.c
  2.  * Copyright 1985 Massachusetts Institute of Technology
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <sys/dir.h>
  8. #include "findfile.h"
  9.  
  10. int
  11. findfileindir(area, name, mag, s, nname, nmag)
  12.      char *area,*name,*s,*nname;
  13.      int mag,*nmag;
  14. {
  15.   FILE *f;
  16.   char buf[BUFSIZ];
  17.   int found = 0;
  18.     
  19.   sprintf(s,"%s/SUBDIR",area);
  20.   if (!access(s,0)) sprintf(s,"%s/%s/%s.%dpxl",area,name,name,mag);
  21.   else sprintf(s,"%s/%s.%dpxl",area,name,mag);
  22.   if (!access(s,4)) {
  23.     strcpy(nname,name);
  24.     *nmag = mag;
  25.     return(-1);
  26.   } else {
  27.     sprintf(buf,"%s/NEEDED",area);
  28.     if (!access(buf,2)) {
  29.       sprintf(s,"%s.%dpxl\n",name,mag);
  30.       f = fopen(buf,"r+");
  31.       while (fgets(buf,sizeof(buf),f)) if (!strcmp(buf,s)) found++;
  32.       if (!found) fputs(s,f);
  33.       fclose(f);
  34.     }
  35.     return(0);
  36.   }
  37. }
  38.  
  39.  
  40. /* true if it found a file, false otherwise; name is in s */
  41. int findfile(dirvec,dirveclen,area, name, mag, s, nname, nmag)
  42.      char *dirvec[],*area,*name,*s,*nname;
  43.      int dirveclen,mag,*nmag;
  44. {
  45.   int i,point;
  46.   char family[128];
  47.  
  48.   strcpy(nname,name);
  49.   *nmag = mag;
  50.   point = -1;
  51.   (void) sscanf(name,"%[^0123456789.]%d",family,&point);
  52.  
  53.   /* First check dir area given in DVI file */
  54.   if (*area && findfileindir(area, name, mag, s, nname, nmag)) return(-1);
  55.   
  56.   /* Then check along dirvec */
  57.   for (i = 0; i < dirveclen; i++) 
  58.     if (findfileindir(dirvec[i], name, mag, s, nname, nmag)) return(-1);
  59.  
  60.   /* next check for closest magnification along dirvec */
  61.   return(findanyfile(dirvec,dirveclen,family,point,mag,name,s,nname,nmag));
  62. }
  63.   
  64. int strdiff(s1,s2)
  65.      char *s1,*s2;
  66. {
  67.   register int diff = 0;
  68.  
  69.   while (*s1 && *s2) diff += abs(*s1++ - *s2++);
  70.   while (*s1) diff += *s1++;
  71.   while (*s2) diff += *s2++;
  72.   return(diff);
  73. }
  74.  
  75. scanpdir(dir,name,
  76.      family,point,mag,
  77.      bestfamily,bestname,bestpoint,bestmag,
  78.      min_df,min_dp,min_dm)
  79.      char *dir,*name,*family,*bestfamily,*bestname;
  80.      int point,mag,*bestpoint,*bestmag,*min_df,*min_dp,*min_dm;
  81. {
  82.   DIR *dirstream;
  83.   struct direct *dirrecord;
  84.   char qfamily[128];
  85.   int qpoint,qmag,df,dp,dm;
  86.  
  87.   if (dirstream = opendir(dir)) {
  88.     while (dirrecord = readdir(dirstream)) {
  89.       if (!strcmp(dirrecord->d_name+dirrecord->d_namlen-3,"pxl")) {
  90.     qpoint = -1; qmag = -1;
  91.     (void) sscanf(dirrecord->d_name,"%[^0123456789.]%d.%d",
  92.               qfamily,&qpoint,&qmag);
  93.     df = strdiff(family,qfamily);
  94.     dp = abs(point - qpoint);
  95.     dm = abs(mag - qmag);
  96.     if ((df < *min_df)
  97.         || (df == *min_df && dp < *min_dp)
  98.           || (df == *min_df && dp == *min_dp && dm < *min_dm)) {
  99.         sprintf(bestname,"%s/%s",dir,dirrecord->d_name);
  100.         strcpy(bestfamily,qfamily);
  101.         *bestpoint = qpoint;
  102.         *bestmag = qmag;
  103.         *min_df = df;
  104.         *min_dp = dp;
  105.         *min_dm = dm;
  106.       }
  107.       }
  108.     }
  109.     closedir(dirstream);
  110.   }
  111. }
  112.  
  113. scandir(dir,name,
  114.     family,point,mag,
  115.     bestfamily,bestname,bestpoint,bestmag,
  116.     min_df,min_dp,min_dm)
  117.      char *dir,*name,*family,*bestfamily,*bestname;
  118.      int point,mag,*bestpoint,*bestmag,*min_df,*min_dp,*min_dm;
  119. {
  120.   DIR *dirstream;
  121.   struct direct *dirrecord;
  122.   int df;
  123.   char pdir[MAXNAMLEN];
  124.  
  125.   if (dirstream = opendir(dir)) {
  126.     while (dirrecord = readdir(dirstream)) {
  127.       if (dirrecord->d_name[0] != '.') {
  128.     df = strdiff(name,dirrecord->d_name);
  129.     if (df <= *min_df) {
  130.       sprintf(pdir,"%s/%s",dir,dirrecord->d_name);
  131.       scanpdir(pdir,name,
  132.            family,point,mag,
  133.            bestfamily,bestname,bestpoint,bestmag,
  134.            min_df,min_dp,min_dm);
  135.     }
  136.       }
  137.     }
  138.     closedir(dirstream);
  139.   }
  140. }
  141.  
  142.  
  143. /* finds the best match to the desired font */
  144. int findanyfile(dirvec,dirveclen,family,point,mag,name,s,nname,nmag)
  145.      char *dirvec[],*family,*name,*s,*nname;
  146.      int dirveclen,point,mag,*nmag;
  147. {
  148.   char foo[MAXNAMLEN],bestname[MAXNAMLEN],bestfamily[128];
  149.   int min_df,min_dp,min_dm,df,dp,dm,i,bestpoint,bestmag;
  150.   
  151.   bestname[0] = '\0'; 
  152.   min_df = min_dp = min_dm = 9999999;
  153.   for (i = 0; i < dirveclen; i++) {
  154.     sprintf(foo,"%s/SUBDIR",dirvec[i]);
  155.     if (!access(foo,0)) scandir(dirvec[i],name,
  156.                 family,point,mag,
  157.                 bestfamily,bestname,&bestpoint,&bestmag,
  158.                 &min_df,&min_dp,&min_dm);
  159.     else scanpdir(dirvec[i],name,
  160.           family,point,mag,
  161.           bestfamily,bestname,&bestpoint,&bestmag,
  162.           &min_df,&min_dp,&min_dm);
  163.   }
  164.   if (bestname[0]) {
  165.     if (bestpoint > 0) sprintf(nname,"%s%d",bestfamily,bestpoint);
  166.     else strcpy(nname,bestfamily);
  167.     *nmag = bestmag;
  168.     strcpy(s,bestname);
  169.     if ((strcmp(bestfamily,family)
  170.      || bestpoint != point || abs(bestmag - mag) > 2)) 
  171.       fprintf(stderr,
  172.           "Substituted font %s at mag %d for %s at mag %d.\n",
  173.           nname,(bestmag * 4 + 3) / 6,
  174.           name,(mag * 4 + 3) / 6);
  175.     return(-1);
  176.   }
  177.   return(0);
  178. }
  179.   
  180.